package wiki.hitime.stl.daq.manager;

import com.alibaba.fastjson.JSON;
import wiki.hitime.stl.daq.bean.bo.DataMsgRuleHistoryBO;
import wiki.hitime.stl.daq.bean.db.*;
import wiki.hitime.stl.daq.bean.dto.manage.MsgRuleDTO;
import wiki.hitime.stl.daq.bean.dto.manage.MsgRuleDetailConfigDTO;
import wiki.hitime.stl.daq.bean.dto.req.*;
import wiki.hitime.stl.daq.bean.dto.req.MsgRuleGetReqDTO;
import wiki.hitime.stl.daq.bean.dto.req.MsgRuleUpdateReqDTO;
import wiki.hitime.stl.daq.enums.OperateActionEnum;
import wiki.hitime.stl.daq.exception.ServiceException;
import wiki.hitime.stl.daq.mapper.DaqMsgRuleDetailConfigMapper;
import wiki.hitime.stl.daq.mapper.DaqMsgRuleHistoryMapper;
import wiki.hitime.stl.daq.mapper.DaqMsgRuleMapper;
import wiki.hitime.stl.daq.util.UserContextUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import tk.mybatis.mapper.entity.Example;
import wiki.hitime.stl.daq.bean.db.DaqMsgRule;
import wiki.hitime.stl.daq.bean.db.DaqMsgRuleDetailConfig;
import wiki.hitime.stl.daq.bean.db.DaqMsgRuleHistory;

import java.util.List;

/**
 * @author zhangdaoping
 * @create 2019-07-18 14:13
 */
@Service
public class DaqMsgRuleManager {

    private DaqMsgRuleMapper daqMsgRuleMapper;
    private DaqMsgRuleHistoryMapper daqMsgRuleHistoryMapper;
    private DaqMsgRuleDetailConfigMapper daqMsgRuleDetailConfigMapper;
    private DaqMsgRuleDetailConfigManager daqMsgRuleDetailConfigManager;

    public DaqMsgRuleManager(DaqMsgRuleMapper daqMsgRuleMapper,
                             DaqMsgRuleHistoryMapper daqMsgRuleHistoryMapper,
                             DaqMsgRuleDetailConfigMapper daqMsgRuleDetailConfigMapper,
                             DaqMsgRuleDetailConfigManager daqMsgRuleDetailConfigManager) {
        this.daqMsgRuleMapper = daqMsgRuleMapper;
        this.daqMsgRuleHistoryMapper = daqMsgRuleHistoryMapper;
        this.daqMsgRuleDetailConfigMapper = daqMsgRuleDetailConfigMapper;
        this.daqMsgRuleDetailConfigManager = daqMsgRuleDetailConfigManager;
    }

    /**
     * 获取规则
     *
     * @param checkRuleId
     * @return
     */
    public DaqMsgRule loadRule(Long checkRuleId) {
        Example selectExample = new Example(DaqMsgRule.class, true, true);
        selectExample.createCriteria().andEqualTo("checkRuleId", checkRuleId).andEqualTo("isDelete", Boolean.FALSE);
        return daqMsgRuleMapper.selectOneByExample(selectExample);
    }

    /**
     * 添加规则
     *
     * @param msgRuleDTO 规则DTO
     * @return
     */
    public Long add(MsgRuleDTO msgRuleDTO) {
        DaqMsgRule daqMsgRule = DaqMsgRule.builder()
                .executeRuleId(msgRuleDTO.getExecuteRuleId())
                .checkRuleId(msgRuleDTO.getCheckRuleId())
                .ruleName(msgRuleDTO.getRuleName())
                .msgType(msgRuleDTO.getMsgType())
                .msgReceiver(msgRuleDTO.getMsgReceiver())
                .msgTemplate(msgRuleDTO.getMsgTemplate())
                .remark(msgRuleDTO.getRemark())
                .ctlVersion(1L)
                .createdUserId(UserContextUtil.getJobNumber())
                .createdUser(UserContextUtil.getTrueName())
                .modifiedUserId(UserContextUtil.getJobNumber())
                .modifiedUser(UserContextUtil.getTrueName())
                .build();
        daqMsgRuleMapper.insertSelective(daqMsgRule);
        Long ruleId = daqMsgRule.getId();
        daqMsgRuleDetailConfigManager.addList(ruleId, msgRuleDTO.getMsgRuleDetailConfigList());
        this.addHistory(ruleId);
        return ruleId;
    }

    private void addHistory(Long ruleId) {
        DaqMsgRuleHistory daqMsgRuleHistory = new DaqMsgRuleHistory();
        DaqMsgRule daqMsgRule = daqMsgRuleMapper.selectByPrimaryKey(ruleId);
        BeanUtils.copyProperties(daqMsgRule, daqMsgRuleHistory);
        daqMsgRuleHistory.setIsDelete(Boolean.FALSE);
        daqMsgRuleHistory.setRuleId(daqMsgRule.getId());
        // 查询详细配置
        Example detailSelectExample = new Example(DaqMsgRuleDetailConfig.class, true, true);
        detailSelectExample.createCriteria().andEqualTo("msgRuleId", daqMsgRule.getId());
        List<DaqMsgRuleDetailConfig> detailConfigList = daqMsgRuleDetailConfigMapper.selectByExample(detailSelectExample);
        // 保存历史记录
        DataMsgRuleHistoryBO dataMsgRuleHistoryBO = DataMsgRuleHistoryBO.builder()
                .daqMsgRule(daqMsgRule)
                .daqMsgRuleDetailConfigList(detailConfigList)
                .build();
        OperateActionEnum operateActionEnum = daqMsgRule.getCtlVersion() == 1 ? OperateActionEnum.ADD : OperateActionEnum.UPDATE;
        operateActionEnum = Boolean.TRUE.equals(daqMsgRule.getIsDelete()) ? OperateActionEnum.DELETE : operateActionEnum;
        daqMsgRuleHistory.setOperateAction(operateActionEnum.getStatus());
        daqMsgRuleHistory.setOperateData(JSON.toJSONString(dataMsgRuleHistoryBO));
        daqMsgRuleHistoryMapper.insertSelective(daqMsgRuleHistory);
    }

    /**
     * 获取DTO
     *
     * @param reqDTO 请求实体
     * @return
     */
    public MsgRuleDTO getDTO(MsgRuleGetReqDTO reqDTO) {
        return getDTO(reqDTO.getId(), reqDTO.getCheckRuleId());
    }

    /**
     * 获取DTO
     *
     * @param id
     * @param checkRuleId
     * @return
     */
    public MsgRuleDTO getDTO(Long id, Long checkRuleId) {
        Example example = new Example(DaqMsgRule.class, true, true);
        example.createCriteria().andEqualTo("isDelete", Boolean.FALSE);
        Example.Criteria orCriteria = example.createCriteria();
        if (id != null) {
            orCriteria.orEqualTo("id", id);
        }
        if (checkRuleId != null) {
            orCriteria.orEqualTo("checkRuleId", checkRuleId);
        }
        example.and(orCriteria);
        DaqMsgRule daqMsgRule = daqMsgRuleMapper.selectOneByExample(example);
        if (daqMsgRule == null) {
            return null;
        }
        List<MsgRuleDetailConfigDTO> msgRuleDetailConfigList = daqMsgRuleDetailConfigManager.listDTO(daqMsgRule.getId(), daqMsgRule.getMsgType());
        return convertDTO(daqMsgRule, msgRuleDetailConfigList);
    }

    private MsgRuleDTO convertDTO(DaqMsgRule daqMsgRule, List<MsgRuleDetailConfigDTO> msgRuleDetailConfigList) {
        MsgRuleDTO msgRuleDTO = new MsgRuleDTO();
        BeanUtils.copyProperties(daqMsgRule, msgRuleDTO);
        msgRuleDTO.setMsgRuleDetailConfigList(msgRuleDetailConfigList);
        return msgRuleDTO;
    }

    /**
     * 修改规则
     *
     * @param reqDTO 请求实体
     * @return 修改结果，true-成功，false-失败
     */
    public Boolean updateRule(MsgRuleUpdateReqDTO reqDTO) throws ServiceException {
        MsgRuleDTO ruleDTO = reqDTO.getMsgRuleDTO();
        DaqMsgRule daqRule = daqMsgRuleMapper.selectByPrimaryKey(ruleDTO.getId());
        if (daqRule == null) {
            throw new ServiceException("未查到待修改的消息规则");
        }
        BeanUtils.copyProperties(ruleDTO, daqRule);
        daqRule.setCtlVersion(daqRule.getCtlVersion() + 1);
        daqRule.setModifiedUserId(UserContextUtil.getJobNumber());
        daqRule.setModifiedUser(UserContextUtil.getTrueName());
        Example updateExample = new Example(DaqMsgRule.class, true, true);
        updateExample.createCriteria().andEqualTo("id", daqRule.getId()).andEqualTo("ctlVersion", daqRule.getCtlVersion() - 1);
        int count = daqMsgRuleMapper.updateByExampleSelective(daqRule, updateExample);
        count += daqMsgRuleDetailConfigManager.updateList(daqRule.getMsgType(), ruleDTO.getMsgRuleDetailConfigList());
        if (count > 0) {
            this.addHistory(daqRule.getId());
        }
        return count > 0;
    }

    /**
     * 删除消息规则
     *
     * @param checkRuleId
     * @return
     */
    public Boolean deleteRule(Long checkRuleId) {
        Example selectExample = new Example(DaqMsgRule.class, true, true);
        selectExample.createCriteria().andEqualTo("checkRuleId", checkRuleId).andEqualTo("isDelete", Boolean.FALSE);
        DaqMsgRule daqMsgRule = daqMsgRuleMapper.selectOneByExample(selectExample);
        Assert.notNull(daqMsgRule, "删除规则查询规则为空");
        daqMsgRule.setCtlVersion(daqMsgRule.getCtlVersion() + 1);
        daqMsgRule.setModifiedUserId(UserContextUtil.getJobNumber());
        daqMsgRule.setModifiedUser(UserContextUtil.getTrueName());
        daqMsgRule.setIsDelete(Boolean.TRUE);
        daqMsgRuleMapper.updateByPrimaryKeySelective(daqMsgRule);
        daqMsgRuleDetailConfigManager.delete(daqMsgRule.getId());
        this.addHistory(daqMsgRule.getId());
        return true;
    }
}
